package laf.agents;



import jade.content.ContentManager;
import jade.content.lang.sl.SLCodec;
import jade.content.onto.BeanOntologyException;
import jade.core.Agent;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.util.Logger;
import laf.behaviours.BroadcastDescriptionBehaviour;
import laf.behaviours.BroadcastObservationBehaviour;
import laf.behaviours.ObservationBehaviour;
import laf.behaviours.TickerBehaviour;
import laf.behaviours.TimerBehaviour;
import laf.env.Enviroment;
import laf.env.ObjectIdentifier;
import laf.env.Observation;
import laf.onto.LAFOntology;

public class CognitiveAgent extends Agent {
	
	private class Broadcast extends TimerBehaviour {

		public Broadcast() {
			super(CognitiveAgent.this, 1);
			// TODO Auto-generated constructor stub
		}

		@Override
		protected void onTick() {
			
			
		}
		
	}
	private class Observe extends TickerBehaviour {

		public Observe() {
			super(CognitiveAgent.this, 1, 2);
		}

		@Override
		protected void onTick() {
			for (ObjectIdentifier objId : Enviroment.getInstance().getObjects()) {
				myAgent.addBehaviour(new ObservationBehaviour(myAgent, objId) {

					@Override
					protected void handleResult(Observation observation) {
						observationBase.add(observation);
						logger.info("New observation: " + observation.toString());
						addBehaviour(new BroadcastObservationBehaviour(CognitiveAgent.this, observation));
						
					}
				});
			}
		}
	}

	
	public final static int CREDIBILITY_LEVEL = 100;
	private static final long serialVersionUID = 2494507918633992525L;

	public final static String SERVICE_TYPE = "CognitiveAgent";
	
	private double correlationLevel = 0.9;

	private long credibilityLevel = 100;

	private LanguageSymbolDictionary dictionary;
	private LanguageSymbolGroundingHistory groundingHistory;
	
	private Logger logger;

	private final ObservationBase observationBase = new ObservationBase();
	
	public double getCorrelationLevel() {
		return correlationLevel;
	}

	public long getCredibilityLevel() {
		return credibilityLevel;
	}

	public LanguageSymbolDictionary getDictionary() {
		return dictionary;
	}

	public Logger getLogger() {
		return logger;
	}
	
	public ObservationBase getObservationBase() {
		return observationBase;
	}

	/**
	 * Registers service provided by agent
	 * 
	 * @param serviceType type of service
	 */
	protected void registerService() {
		ServiceDescription sd = new ServiceDescription();
		sd.setType(SERVICE_TYPE);
		sd.setName(SERVICE_TYPE + "-" + getLocalName());
		// TODO: add languages, protocols and ontologies do DF description
		DFAgentDescription dfd = new DFAgentDescription();
		dfd.setName(getAID());
		dfd.addServices(sd);

		try {
			DFService.register(this, dfd);
			logger.info("Service registered");
		} catch (FIPAException fe) {
			logger.severe(fe.getLocalizedMessage());
			fe.printStackTrace();
		}
	}

	public void setCorrelationLevel(double correlationLevel) {
		this.correlationLevel = correlationLevel;
	}

	public void setCredibilityLevel(long credibilityLevel) {
		this.credibilityLevel = credibilityLevel;
	}

	public void setDictionary(LanguageSymbolDictionary dictionary) {
		this.dictionary = dictionary;
	}

	public void setLogger(Logger logger) {
		this.logger = logger;
	}

	@Override
	protected void setup() {
		logger = Logger.getMyLogger(getClass().getName() + "." + getLocalName());
		
		Object[] args = getArguments();
		if (args != null && args.length > 0) {
			Object arg1 = args[0];
			if (arg1 instanceof LanguageSymbolDictionary) {
				dictionary = (LanguageSymbolDictionary) arg1;				
			}
		}
		
		if (dictionary == null) {
			dictionary = new LanguageSymbolDictionary(Enviroment.getInstance().getAttributes());
		}
		
		groundingHistory = new LanguageSymbolGroundingHistory(this.getAID());
		
		ContentManager contentManager = getContentManager();
		contentManager.registerLanguage(new SLCodec());
		try {
			contentManager.registerOntology(LAFOntology.getInstance());
		} catch (BeanOntologyException e) {
			logger.severe("Cannot create ontology instance: " + e.getLocalizedMessage());
			doDelete();
			logger.warning("Setup continues after doDelete");
		}
		
		registerService();
		addBehaviour(new Observe());
	}

	public LanguageSymbolGroundingHistory getGroundingHistory() {
		return groundingHistory;
	}

	public void setGroundingHistory(LanguageSymbolGroundingHistory groundingHistory) {
		this.groundingHistory = groundingHistory;
	}
}
